package com.older.wptsb.config;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.older.wptsb.domain.po.UserElderRel;
import com.older.wptsb.mapper.UserElderRelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

@Component
public class AlertWebSocketHandler extends TextWebSocketHandler {

    // 按社区ID存储WebSocket会话
    private static final ConcurrentHashMap<String, CopyOnWriteArrayList<WebSocketSession>> communitySessions = new ConcurrentHashMap<>();

    // 按用户ID存储WebSocket会话，用于定向推送
    private static final ConcurrentHashMap<String, WebSocketSession> userSessions = new ConcurrentHashMap<>();

    private static final ObjectMapper objectMapper = new ObjectMapper();

    // 注入UserElderRelMapper用于查询用户与老人的绑定关系
    private static UserElderRelMapper userElderRelMapper;

    @Autowired
    public void setUserElderRelMapper(UserElderRelMapper userElderRelMapper) {
        AlertWebSocketHandler.userElderRelMapper = userElderRelMapper;
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        try {
            // 从URL参数中获取社区ID和用户ID
            String communityId = getCommunityIdFromSession(session);
            String userId = getUserIdFromSession(session);

            if (userId != null) {
                // 按用户ID存储会话，用于定向推送
                userSessions.put(userId, session);
            }

            if (communityId != null) {
                communitySessions.computeIfAbsent(communityId, k -> new CopyOnWriteArrayList<>()).add(session);
                System.out.println("社区 " + communityId + " 的WebSocket连接已建立，当前连接数: " + communitySessions.get(communityId).size());
            } else {
                // 如果没有指定社区ID，则添加到通用会话列表
                communitySessions.computeIfAbsent("general", k -> new CopyOnWriteArrayList<>()).add(session);
                System.out.println("通用WebSocket连接已建立");
            }

            if (userId != null) {
                System.out.println("用户 " + userId + " 的WebSocket连接已建立");
            }
        } catch (Exception e) {
            System.err.println("建立WebSocket连接时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        try {
            // 从所有社区会话中移除关闭的会话
            for (List<WebSocketSession> sessions : communitySessions.values()) {
                sessions.remove(session);
            }

            // 从用户会话中移除关闭的会话
            userSessions.values().remove(session);

            System.out.println("WebSocket连接已关闭，状态: " + status);
        } catch (Exception e) {
            System.err.println("关闭WebSocket连接时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        System.err.println("WebSocket传输错误: " + exception.getMessage());
        exception.printStackTrace();

        // 移除出错的会话
        for (List<WebSocketSession> sessions : communitySessions.values()) {
            sessions.remove(session);
        }

        // 从用户会话中移除出错的会话
        userSessions.values().remove(session);

        if (session.isOpen()) {
            session.close();
        }
    }

    /**
     * 从会话中提取社区ID
     * @param session WebSocket会话
     * @return 社区ID
     */
    private String getCommunityIdFromSession(WebSocketSession session) {
        String query = session.getUri().getQuery();
        if (query != null) {
            String[] params = query.split("&");
            for (String param : params) {
                if (param.startsWith("communityId=")) {
                    return param.substring(12);
                }
            }
        }
        return null;
    }

    /**
     * 从会话中提取用户ID
     * @param session WebSocket会话
     * @return 用户ID
     */
    private String getUserIdFromSession(WebSocketSession session) {
        String query = session.getUri().getQuery();
        if (query != null) {
            String[] params = query.split("&");
            for (String param : params) {
                if (param.startsWith("userId=")) {
                    return param.substring(7);
                }
            }
        }
        return null;
    }

    /**
     * 向指定社区的所有客户端发送告警消息
     * @param communityId 社区ID
     * @param alertMessage 告警消息
     * @throws IOException IO异常
     */
    public static void sendAlertToCommunity(String communityId, Object alertMessage) throws IOException {
        List<WebSocketSession> sessions = communitySessions.get(communityId);
        if (sessions != null) {
            String messageJson = objectMapper.writeValueAsString(alertMessage);
            TextMessage message = new TextMessage(messageJson);

            // 创建一个临时列表来避免并发修改异常
            CopyOnWriteArrayList<WebSocketSession> sessionsToRemove = new CopyOnWriteArrayList<>();

            for (WebSocketSession session : sessions) {
                if (session.isOpen()) {
                    try {
                        session.sendMessage(message);
                    } catch (Exception e) {
                        System.err.println("向会话发送消息失败: " + e.getMessage());
                        sessionsToRemove.add(session);
                    }
                } else {
                    sessionsToRemove.add(session);
                }
            }

            // 移除已关闭的会话
            for (WebSocketSession session : sessionsToRemove) {
                sessions.remove(session);
            }
        }
    }

    /**
     * 向所有连接的客户端发送告警消息
     * @param alertMessage 告警消息
     * @throws IOException IO异常
     */
    public static void broadcastAlert(Object alertMessage) throws IOException {
        String messageJson = objectMapper.writeValueAsString(alertMessage);
        TextMessage message = new TextMessage(messageJson);

        for (List<WebSocketSession> sessions : communitySessions.values()) {
            // 创建一个临时列表来避免并发修改异常
            CopyOnWriteArrayList<WebSocketSession> sessionsToRemove = new CopyOnWriteArrayList<>();

            for (WebSocketSession session : sessions) {
                if (session.isOpen()) {
                    try {
                        session.sendMessage(message);
                    } catch (Exception e) {
                        System.err.println("向会话发送消息失败: " + e.getMessage());
                        sessionsToRemove.add(session);
                    }
                } else {
                    sessionsToRemove.add(session);
                }
            }

            // 移除已关闭的会话
            for (WebSocketSession session : sessionsToRemove) {
                sessions.remove(session);
            }
        }
    }

    /**
     * 向指定用户发送告警消息
     * @param userId 用户ID
     * @param alertMessage 告警消息
     * @throws IOException IO异常
     */
    public static void sendAlertToUser(String userId, Object alertMessage) throws IOException {
        WebSocketSession session = userSessions.get(userId);
        if (session != null && session.isOpen()) {
            try {
                String messageJson = objectMapper.writeValueAsString(alertMessage);
                TextMessage message = new TextMessage(messageJson);
                session.sendMessage(message);
            } catch (Exception e) {
                System.err.println("向用户 " + userId + " 发送消息失败: " + e.getMessage());
                // 移除失败的会话
                userSessions.remove(userId);
            }
        }
    }

    /**
     * 向与指定老人绑定的所有用户发送告警消息
     * @param elderId 老人ID
     * @param alertMessage 告警消息
     * @throws IOException IO异常
     */
    public static void sendAlertToRelatedUsers(String elderId, Object alertMessage) throws IOException {
        if (userElderRelMapper != null) {
            // 查询与该老人绑定的所有用户
            List<UserElderRel> userElderRels = userElderRelMapper.selectList(
                new QueryWrapper<UserElderRel>().eq("elder_id", elderId)
            );

            if (userElderRels != null && !userElderRels.isEmpty()) {
                // 向所有绑定该老人的用户发送定向推送
                for (UserElderRel rel : userElderRels) {
                    sendAlertToUser(rel.getUserId(), alertMessage);
                }
            }
        } else {
            // 如果无法获取UserElderRelMapper，则进行广播（备用方案）
            broadcastAlert(alertMessage);
        }
    }

    /**
     * 获取当前所有用户的会话映射
     * @return 用户会话映射
     */
    public static ConcurrentHashMap<String, WebSocketSession> getUserSessions() {
        return userSessions;
    }
}
